﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Clandestine.Battle
{ 
    public delegate void CombatantDie(Combatant c);
    public delegate void CombatantDamage(Combatant c,int amount);
    public delegate void CombatantHeal(Combatant c, int amount);
    public delegate void CombatantStatsChange();
    public delegate void CombatantAfflicted(Combatant c, BattleAffliction affliction);
    public delegate void CombatantAfflictionRemoved(Combatant c, BattleAffliction affliction);

    public enum BattleAffliction
    {
        Poisoned,
        Asleep
    }

    public abstract class Combatant
    {
        public string Name = string.Empty;

        public int MaxHP = 300;
        private int hp = 100;
        public int HP
        {
            get { return hp; }
            set
            {
                hp = value;
                if (OnStatsChange != null)
                    OnStatsChange();
                if (hp <= 0)
                    if (OnDie != null)
                        OnDie(this);
            }
        }

        public int MaxMP = 100;
        private int mp = 20;
        public int MP
        {
            get { return mp; }
            set
            {
                mp = value;
                if (OnStatsChange != null)
                    OnStatsChange();
            }
        }

        public bool Alive
        {
            get
            {
                if (hp > 0)
                    return true;
                else
                    return false;
            }
        }

        internal bool poisoned = false;
        public virtual bool Poisoned
        {
            get { return poisoned; }
            set 
            { 
                poisoned = value;
                if (OnAffliction != null)
                    OnAffliction(this, BattleAffliction.Poisoned);
            }
        }
        public int PoisonDamage = 0;

        internal bool asleep = false;
        public virtual bool Asleep
        {
            get { return asleep; }
            set
            {
                asleep = value;
                if (OnAffliction != null)
                    OnAffliction(this, BattleAffliction.Asleep);
            }
        }

        public event CombatantDie OnDie;
        public event CombatantDamage OnDamage;
        public event CombatantHeal OnHeal;
        public event CombatantAfflicted OnAffliction;
        public event CombatantAfflictionRemoved OnAfflictionRemoved;
        public event CombatantStatsChange OnStatsChange;

        public abstract Sprite Sprite { get; }

        public abstract void InitialiseSprite();
        public abstract void DeinitialiseSprite();

        public void TakeDamage(int amount)
        {
            if (OnDamage != null)
                OnDamage((Combatant)this, amount);
            this.HP -= amount;
        }

        public void Heal(int amount)
        {
            if (this.MaxHP < (this.HP + amount))
                amount = this.MaxHP - this.HP;
            if (OnHeal != null)
                OnHeal((Combatant)this, amount);
            this.HP += amount;
        }
        
        public void Poision(int poisonDamage)
        {
            if (!this.Poisoned)
            {
                this.Poisoned = true;
                this.PoisonDamage = poisonDamage;
            }
        }

        public void PutToSleep()
        {
            this.Asleep = true;
        }

        public virtual void Dispose()
        {
            Sprite.Dispose();
        }

        public static Sprite ToSprite(Combatant c) // For List<>.Covert<>
        {
            return c.Sprite;
        }
    }
}
